package com.zenaprod.twodcore.graphic.sprite;

import com.zenaprod.framework.exception.NoImageFileInDirException;
import com.zenaprod.framework.functor.Functor;
import com.zenaprod.framework.log.ZLog;

import java.awt.Graphics2D;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
import java.util.List;


public class SimpleSprite extends Observable implements Sprite, Runnable {
    protected static final int FORWARD = 1;
    protected static final int BACKWARD = -1;

    protected List<SpriteImage> spriteImages;
    protected int size = 0;
    protected int imageIndex = 0;
    protected Functor functor;
    protected int direction = FORWARD;
    protected boolean loop = true;
    protected boolean stop = false;
    protected boolean endOnInitialState = true;
    protected int x, y, z;
    protected int width, height;

    public SimpleSprite(int x, int y, int z, int width, int height) {
        this.x = x;
        this.y = y;
        this.z = z;
        this.width = width;
        this.height = height;
        spriteImages = new ArrayList<SpriteImage>();
    }

    public SimpleSprite(String imgDirPath, int imageTime, int x, int y, int z) throws FileNotFoundException, NoImageFileInDirException {
        File imgDir = new File(imgDirPath);
        if(!imgDir.exists()) {
            throw new FileNotFoundException("Directory " + imgDirPath + " does not exist.");
        }
        File[] imgFiles = imgDir.listFiles();
        if(imgFiles.length <= 0) {
            throw new NoImageFileInDirException(imgDir);
        }

        for(File imgFile : imgFiles) {
            addImage(imgFile.getAbsolutePath(), imageTime);
        }
    }

    public void addImage(String imagePath, int imageTime) {
        SpriteImage animImg = new SpriteImage(imagePath, imageTime);
        if(animImg.getWidth() == width && animImg.getHeight() == height) {
            spriteImages.add(animImg);
            size++;
        }
    }


    public void draw(Graphics2D g) {
        if(spriteImages.size() == 0) {
            ZLog.e("No image in sprite");
            return;
        }
        g.drawImage(spriteImages.get(imageIndex).getImage(), x, y, null);
    }


    public void run() {
        stop = false;
        if(functor != null) {
            functor.run();
        }
        while(!stop) {
            try {
                Thread.sleep(spriteImages.get(imageIndex).getImageTime());
            } catch (InterruptedException e) {
                ZLog.e(e);
            }

            int nextIndex = imageIndex + direction;
            if(nextIndex >= size) {
                nextIndex = 0;
                if(!loop) {
                    stop();
                    break;
                }
            } else if(nextIndex == 0) {
                nextIndex = size - 1;
                if(!loop) {
                    stop();
                    break;
                }
            }
            imageIndex = nextIndex;
            notifyObservers(this);
        }

        if(endOnInitialState) {
            imageIndex = 0;
            notifyObservers(this);
        }
    }

    public void stop() {
        stop = true;
    }



    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getZ() {
        return z;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }
}
